package com.study4j.common.utils;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import com.study4j.common.enums.EnumSysCode;
import com.study4j.common.enums.IEnumCode;
import com.study4j.common.exception.BaseException;
import com.study4j.common.model.ResultModel;

/**
 * @description 响应结果实体工具类
 * @author jiangbin
 */
public class RespUtil {
	
	private Map<String, Object> mapData;
	
	public Map<String, Object> put(String key,Object value) {
		if(mapData ==  null) {
			mapData = new HashMap<String, Object>();
		}
		mapData.put(key, value);
		return mapData;
	}

	public static ResultModel success(Object data) {
		return getResultModel(EnumSysCode.SUCCESS, data);
	}

	public static ResultModel success() {
		return getResultModel(EnumSysCode.SUCCESS, null);
	}

	public static ResultModel result(IEnumCode code, Object data) {
		return setResultModel(code, data);
	}

	public static ResultModel error() {
		return getResultModel(EnumSysCode.ERROR, null);
	}

	public static ResultModel error(String msg) {
		ResultModel resultModel = new ResultModel();
		resultModel.setMessage(msg);
		resultModel.setCode(EnumSysCode.ERROR.getCode());
		resultModel.setData(null);
		return resultModel;
	}

	// 将返回的数据转换为json数据
	private static ResultModel getResultModel(IEnumCode code, Object data) {
		String body = null;
		if (data != null) {
			body = JsonUtil.toJson(data);
		}
		return setResultModel(code, body);
	}

	private static ResultModel setResultModel(IEnumCode code, Object body) {
		ResultModel resultModel = new ResultModel();
		resultModel.setMessage(code.getMessage());
		resultModel.setCode(code.getCode());
		resultModel.setData(body);
		return resultModel;
	}

	public static void error(Exception ex, HttpServletResponse response) throws IOException {
		ResultModel responseModel = new ResultModel();
		// 判断异常是否为项目的业务异常
		if (ex instanceof BaseException) {
			setErrorResponse(responseModel, ex);
		} else {
			Throwable throwable = ex.getCause();
			if (null != throwable && throwable instanceof BaseException) {
				setErrorResponse(responseModel, throwable);
			} else {
				responseModel.setMessage(EnumSysCode.ERROR.getMessage());
				responseModel.setCode(EnumSysCode.ERROR.getCode());
			}
		}
		headerResponse(response);
		writer((ResultModel) responseModel, response);
	}

	public static ResultModel error(Exception ex) {
		ResultModel responseModel = new ResultModel();
		if (ex instanceof BaseException) {
			setErrorResponse(responseModel, ex);
		} else {
			Throwable throwable = ex.getCause();
			if (null != throwable && throwable instanceof BaseException) {
				setErrorResponse(responseModel, throwable);
			} else {
				responseModel.setCode(EnumSysCode.ERROR.getCode());
				responseModel.setMessage(EnumSysCode.ERROR.getMessage());
			}
		}

		return responseModel;
	}

	private static void writer(ResultModel responseModel, ServletResponse response) {
		headerResponse(response);
		PrintWriter pw = null;

		try {
			pw = response.getWriter();
			pw.write(JsonUtil.toJson(responseModel));
		} catch (IOException arg6) {
			arg6.printStackTrace();
		} finally {
			pw.flush();
			pw.close();
		}

	}

	public static void writer(EnumSysCode code, ServletResponse response) {
		writer(getResultModel(code, null), response);
	}

	private static void setErrorResponse(ResultModel responseModel, Throwable throwable) {
		BaseException be = (BaseException) throwable;
		if (be.getCode() != null) {
			responseModel.setCode(be.getCode().getCode());
			responseModel.setMessage(be.getMessage());
		} else {
			responseModel.setCode(EnumSysCode.ERROR.getCode());
			responseModel.setMessage(EnumSysCode.ERROR.getMessage());
		}

	}

	private static void headerResponse(ServletResponse response) {
		HttpServletResponse resp = (HttpServletResponse) response;
		resp.setHeader("Content-type", "text/html;charset=UTF-8");
		resp.setCharacterEncoding("UTF-8");
	}
}
